import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:studymanage/core/event_bus.dart';
import 'package:studymanage/core/global.dart';
import 'package:studymanage/core/request_model.dart';

import 'project_config.dart';

class Request {
  Dio dio;

  // 工厂模式(dart单例模式)
  factory Request() => getInstance();

  static Request get instance => getInstance();
  static Request _instance;

  // 初始化
  Request._internal() {
    dio = new Dio(BaseOptions(
      baseUrl: Profile().serverUrl,
      connectTimeout: 10000,
      receiveTimeout: 10000,
    ));
    setInterceptor();
  }

  static Request getInstance() {
    if (_instance == null) {
      _instance = new Request._internal();
    }
    return _instance;
  }

  setInterceptor() {
    dio.interceptors.add(InterceptorsWrapper(
      // 在请求被发送之前做一些事情
      onRequest: (RequestOptions options) async {
        eventBus.fire(LoadingEvent(false,0));
        options.headers["multi-token"] = Global.profile.token;
        print(Global.profile.token);
        options.headers["Content-Type"] = 'application/json';
        return options;
      },

      // 在返回响应数据之前做一些预处理
      onResponse: (Response response) async {
        eventBus.fire(LoadingEvent(true,0));
        return response;
      },

      // 当请求失败时做一些预处理
      onError: (DioError e) async {
        eventBus.fire(LoadingEvent(true,0));
        if (e.type == DioErrorType.DEFAULT) {
          if (e.message.indexOf("Connection failed") > -1) {
            eventBus.fire(
                RequestEvent(ResponseModel(code: 400, msg: "连接失败")));
            return e;
          } else if (e.message.indexOf("Connection refused") > -1) {
            eventBus.fire(
                RequestEvent(ResponseModel(code: 400, msg: "连接被拒接")));
            return e;
          } else {
            eventBus.fire(RequestEvent(
                ResponseModel(code: 400, msg: "网络错误")));
            return e;
          }
        } else if (e.type == DioErrorType.CONNECT_TIMEOUT) {
          eventBus
              .fire(RequestEvent(ResponseModel(code: 400, msg: "连接超时")));
          return e;
        } else if (e.type == DioErrorType.RESPONSE) {
          if (e.response.statusCode == 401) {
            eventBus.fire(RequestEvent(ResponseModel(
                code: 401, msg: "无权限")));
            return e;
          } else {
            if(e.response.data.containsKey('msg')){
              eventBus.fire(
                  RequestEvent(ResponseModel(code: 400, msg: e.response.data['msg'])));
            }else
            if(e.response.data.containsKey('error_description')){
              eventBus.fire(
                  RequestEvent(ResponseModel(code: 400, msg: e.response.data['error_description'])));
            }else {
              eventBus.fire(
                  RequestEvent(ResponseModel(code: 400, msg: '网络异常')));

            }
            return e;
          }
        } else {
          eventBus.fire(
              RequestEvent(ResponseModel(code: 400, msg: "网络异常")));
          return e;
        }
      },
    ),);
  }

  // post 请求
  Future<ResponseModel> post<T>(String url, {data, cancelToken}) async {
    Response<Map<String, dynamic>> response = await dio.post(
      url,
      data: data,
      cancelToken: cancelToken,
    );

    ResponseModel<T> result = ResponseModel.fromJson(response.data);

    eventBus.fire(new RequestEvent(result));

    return result;
  }
  toast(String message){
    Fluttertoast.showToast(
      msg: message,
      toastLength: Toast.LENGTH_LONG,
      gravity: ToastGravity.TOP,
      timeInSecForIosWeb: 2,
      textColor: Colors.white,
      backgroundColor: Colors.black.withOpacity(0.5),
      fontSize: 12,
    );
  }
}

class Upload{

  Dio dio;

  // 工厂模式(dart单例模式)
  factory Upload() => getInstance();

  static Upload get instance => getInstance();
  static Upload _instance;

  setInterceptor() {
    dio.interceptors.add(InterceptorsWrapper(
      // 在请求被发送之前做一些事情
      onRequest: (RequestOptions options) async {
        eventBus.fire(LoadingEvent(false,0));
        return options;
      },

      // 在返回响应数据之前做一些预处理
      onResponse: (Response response) async {
        eventBus.fire(LoadingEvent(true,0));
        return response;
      },

      // 当请求失败时做一些预处理
      onError: (DioError e) async {
        eventBus.fire(LoadingEvent(true,0));
        if (e.type == DioErrorType.DEFAULT) {
          if (e.message.indexOf("Connection failed") > -1) {
            eventBus.fire(
                RequestEvent(ResponseModel(code: 400, msg: "连接失败")));
            return e;
          } else if (e.message.indexOf("Connection refused") > -1) {
            eventBus.fire(
                RequestEvent(ResponseModel(code: 400, msg: "连接被拒接")));
            return e;
          } else {
            eventBus.fire(RequestEvent(
                ResponseModel(code: 400, msg: "网络错误")));
            return e;
          }
        } else if (e.type == DioErrorType.CONNECT_TIMEOUT) {
          eventBus
              .fire(RequestEvent(ResponseModel(code: 400, msg: "连接超时")));
          return e;
        } else if (e.type == DioErrorType.RESPONSE) {
          if (e.response.statusCode == 401) {
            eventBus.fire(RequestEvent(ResponseModel(
                code: 401, msg: "无权限")));
            return e;
          } else {
            if(e.response.data.containsKey('msg')){
              eventBus.fire(
                  RequestEvent(ResponseModel(code: 400, msg: e.response.data['msg'])));
            }else
            if(e.response.data.containsKey('error_description')){
              eventBus.fire(
                  RequestEvent(ResponseModel(code: 400, msg: e.response.data['error_description'])));
            }else {
              eventBus.fire(
                  RequestEvent(ResponseModel(code: 400, msg: '网络异常')));

            }
            return e;
          }
        } else {
          eventBus.fire(
              RequestEvent(ResponseModel(code: 400, msg: "网络异常")));
          return e;
        }
      },
    ),);
  }
  // 初始化
  Upload._internal() {
    dio = new Dio(BaseOptions(
      baseUrl: Profile().serverUrl,
      connectTimeout: 5000,
      receiveTimeout: 3000,
    ));
  }

  static Upload getInstance() {
    if (_instance == null) {
      _instance = new Upload._internal();
    }
    return _instance;
  }
  // 文件上传
  Future<ResponseModel> upload(String url,  data) async {
    Response<Map<String, dynamic>> response = await dio.post(
      url,
      data: data,
    );

    ResponseModel<Map<String,dynamic>> result = ResponseModel.fromJson(response.data);

    eventBus.fire(new RequestEvent(result));

    return result;
  }


}
